import Observer from "./observer.js";
import Compile from "./compile.js";
const LIFE_CYCLE = [
  "beforeCreate",
  "create",
  "beforeMount",
  "mounted",
  "beforeUpdate",
  "updated",
  "beforeDestroy",
  "destroy"
];
export default class MVVM {
  constructor(props) {
    this.$options = props;
    this._data = this.$options.data;
    this._el = this.$options.el;
    // 数据劫持挂载在最外层
    this._proxyData();
    Observer.create(this._data);
    new Compile(this._el, this);
    this.setHook("mounted");
  }
  _proxyData() {
    const data = this._data;
    const self = this;
    Object.keys(data).forEach(key => {
      Object.defineProperty(this, key, {
        enumerable: true,
        configurable: true,
        get() {
          return data[key];
        },
        set(newVal) {
          if (data[key] === newVal) return;
          data[key] = newVal;
          self.setHook("updated");
        }
      });
    });
  }
  setHook(name) {
    if (!LIFE_CYCLE.find(val => val === name)) return;
    this.$options[name] && this.$options[name].call(this);
  }
}

function action() {
  window.$vm = new MVVM({
    el: "#app",
    data: {
      title: "hello mvvm",
      name: "jtr",
      count: 0
    },
    methods: {
      add() {
        this.count++;
      }
    },
    mounted() {
      this.timer = setInterval(() => {
        this.title += "*";
      }, 500);
    },
    updated() {
      this.title.length > 20 && clearInterval(this.timer);
    }
  });
}

action();
